package com.sh.foa.swagger;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.util.UriComponentsBuilder;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.paths.AbstractPathProvider;
import springfox.documentation.spring.web.paths.Paths;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import com.google.common.base.Predicate;
//import com.ysxn.core.common.util.ServletContextListenerImpl;

import springfox.documentation.RequestHandler;

import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.Tag;

import static com.google.common.base.Predicates.or;
import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.builders.PathSelectors.regex;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

	/*
	 * @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2)
	 * .select() .apis(RequestHandlerSelectors.any()) .build() .apiInfo(apiInfo());
	 * }
	 * 
	 * private ApiInfo apiInfo() { return new ApiInfoBuilder()
	 * .title("对外开放接口API 文档") .description("HTTP对外开放接口") .version("1.0.0")
	 * .termsOfServiceUrl("http://xxx.xxx.com") .license("LICENSE")
	 * .licenseUrl("http://xxx.xxx.com") .build(); }
	 */
	
	private boolean enableSwagger =true; //enableSwagger是多环境配置开关，一般生产环境中不想打开swagger的uil界面，就可以让其为false
	
	 /**
     * 定义api组，
     */
    @Bean
    public Docket talkApi() {
        Predicate<RequestHandler> predicate = new Predicate<RequestHandler>() {
            @Override
            public boolean apply(RequestHandler input) {
                if (input.isAnnotatedWith(ApiOperation.class))//只有添加了ApiOperation注解的method才在API中显示
                    return true;
                return false;
            }
        };
        return new Docket(DocumentationType.SWAGGER_2).enable(enableSwagger)
                .groupName("foa接口")
                .genericModelSubstitutes(DeferredResult.class)
                .useDefaultResponseMessages(false)
                .forCodeGeneration(false)
                .pathProvider(new CustRelativePathProvider())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.stronghill.foa.controller"))
                .apis(predicate)
                .paths(PathSelectors.any())//过滤的接口
                .build()
                .apiInfo(talkApiInfo())
                .tags(new Tag("index", "起始页"), getTalkTags());
		/*
		 * return new Docket(DocumentationType.SWAGGER_2) .enable(enableSwagger)
		 * .forCodeGeneration(true) .pathProvider(new CustRelativePathProvider())
		 * //重定义接口路径 .select() .apis(predicate) .build() .apiInfo(openApiInfo());
		 */
        
    }
    
    private Tag[] getTalkTags() {
        Tag[] tags = { new Tag("foa", "假oa"),new Tag("talk2", "即时通信预留")};
        return tags;
    }    
    
    

    private ApiInfo talkApiInfo() {
        return new ApiInfoBuilder()
                .title("foa服务")//大标题
                .description("foa服务")//详细描述
                .version("0.0.1")//版本
                .termsOfServiceUrl("NO terms of service")
                .contact(new Contact("张劲峰", "http://www.ysyngc.com", "stronghill@mail.ysyngc.com"))//作者
                .license("商业软件")
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                .build();
    }

    
    
    private Predicate<String> paths() {
        return or(regex("/person.*"));
    }
    
    
    private List<ApiKey> securitySchemes() {
        return newArrayList(
                new ApiKey("clientId", "客户端ID", "header"),
                new ApiKey("clientSecret", "客户端秘钥", "header"),
                new ApiKey("accessToken", "客户端访问标识", "header"));
    }

    private List<SecurityContext> securityContexts() {
        return newArrayList(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.regex("/*.*"))
                        .build()
        );
    }

    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return newArrayList(
                new SecurityReference("clientId", authorizationScopes),
                new SecurityReference("clientSecret", authorizationScopes),
                new SecurityReference("accessToken", authorizationScopes));
    }
        
    
    /**
     *对接口路径进行规划和定义； 这里在项目中swagger测试时，接口路径以.do结尾
   **/
    public class CustRelativePathProvider extends AbstractPathProvider {
        private String ROOT = "/foa";       
        
        @Override
        public String getOperationPath(String operationPath) {
            UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
            String uri = Paths.removeAdjacentForwardSlashes(uriComponentsBuilder.path(operationPath).build().toString());
			/*
			 * System.out.println("operationPath:"+operationPath);
			 * System.out.println("uri:"+uri);
			 */          
            return operationPath + ".do";
        }
 
        @Override
        protected String applicationPath() {
			/*
			 * ApplicationContext ac = ServletContextListenerImpl.getApplicationContext();
			 * String appName = ac.getApplicationName();
			 * System.out.println("appName1:"+appName);
			 */
            return ROOT;
        }
 
        @Override
        protected String getDocumentationPath() {
			/*
			 * ApplicationContext ac = ServletContextListenerImpl.getApplicationContext();
			 * String appName = ac.getApplicationName();
			 * System.out.println("appName2:"+appName);
			 */
            return ROOT;
        }
    }
}